//boost headers
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

//project headers
//#include "Validator/Validator.h"
#include "Server/Server.h"
#include "SingletonHolder.h"
#include "Options.h"
#include "DataContainer.h"
#include "Worker.h"
#include "Alive.h"

using namespace std;


int main(void)
{
	try
	{
		SingletonHolder::Instance("mvstupny").WriteMsg("Starting modul Vstupny:");
		Options options;

		Validator::Validator *aValidator = new Validator::Validator(options.GetData("validator_directory"));
		aValidator->Init();

		size_t thread_num = boost::lexical_cast<size_t>(options.GetData("server_threads"));
		Server server(options.GetData("server_port"),thread_num);
		boost::thread th(boost::bind(&Server::Run,&server));
			
		SingletonHolder::Instance("mvstupny").WriteMsg("----------------------Up & Running------------------");

			while(1)
			{
				boost::optional<boost::shared_ptr<ConnectionContainer> > aContainer = server.GetReceived();
				if(aContainer.is_initialized())
				{
					boost::shared_ptr<ConnectionContainer> aReceivedContainer  = aContainer.get();

					if(aReceivedContainer->data->GetCommand() != 'a')		//ak dosli data ne dotaz nato ci zijeme alebo ne
					{
						Worker work(aReceivedContainer->data,aValidator,options.GetData("client_address"),options.GetData("client_port"),options.GetData("store_directory"));

						boost::thread work_th(work); //spustime pracu v vlastnom vlakne
					}
					else	//dosiel dotaz nato ci zijeme
					{
						//  [2/13/2010 Marek Szanyi]
						/************************************************************************/
						/* Odstranil som Alive lebo web page ajtak nic nerobi na reply taze     */
						/* jeto viac menej zbytocne												*/
						/************************************************************************/
						
						//Alive alive(aReceivedContainer->clientAddress,aReceivedContainer->port);
						//alive();
						//boost::thread th_alv(alive);
						continue;
					}
				}
			}

			server.Stop();
			th.join();

		return 0;
	}
	catch(exception &ex)
	{
		SingletonHolder::Instance().WriteEx(ex.what());
	}
}
